package com.stemaini.utility;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.AbstractTableModel;

/**
 * @author Adhik-2008
 * 28 April 2008
 */
public class ModelTabel extends AbstractTableModel
{
    private int jumlahBarisTotal, jumlahBaris;
    private String[] namaKolom;
    private Koneksi theKoneksi;
    private ResultSet rs;
    private LinkedList list;       //kemungkinan ini bkal dibuat node tersendiri
    private String lastQuery;
    private boolean isUsingPilihan;
    private int jumlahDipilih , page, startPage , pageScale;
    
    /** Creates a new instance of ModelTabel */
    /**
     * @param theKoneksi
     * @param namaKolom
     * @param isUsingPilihan
     */
    public ModelTabel(Koneksi theKoneksi , String[] namaKolom , boolean isUsingPilihan)
    {
        this.theKoneksi = theKoneksi;
        this.namaKolom = namaKolom;
        this.lastQuery = "";
        this.isUsingPilihan = isUsingPilihan;
        this.jumlahDipilih = 0;
        this.startPage = 0;
        this.rs = null;
    }

    public void setCurrentPage(int page) {
        if(!isDataEmpty()){
            this.page = page;
            this.startPage = pageScale*(page-1);
            if(jumlahBarisTotal - startPage < pageScale)
                jumlahBaris = jumlahBarisTotal - startPage;
            else
                jumlahBaris = pageScale;
            this.fireTableDataChanged();
        }
    }

    public void setPageScale(int pageScale) {
        if(!isDataEmpty()){
            this.pageScale = pageScale;
            this.jumlahBaris = pageScale;
            this.fireTableDataChanged();
        }
    }
    
    public int getPageRequired()
    {
        if(isDataEmpty())
            return 0;
        
        double pgReq = Math.ceil((double)jumlahBarisTotal/(double)pageScale) ;
        return (int) pgReq;
    }
    
    public String getDataAt(int row, int col)
    {
        try {
            if(rs==null)
                return "";
            
            rs.absolute(row + 1);
            return rs.getObject(col+1).toString();
        } catch (SQLException ex) {
            Logger.getLogger(ModelTabel.class.getName()).log(Level.SEVERE, null, ex);
            return "";
        }
    }
    /**
     * Overide method getValueAt(int row , int col)
     */
    public Object getValueAt(int rowIndex, int columnIndex)
    {
        try
        {
            if(isDataEmpty())
                return null;
            
            if(this.isUsingPilihan){
                if(columnIndex==0)
                    return list.get(rowIndex+startPage); 
                else{
                    rs.absolute(rowIndex+startPage+1);
                    return rs.getObject(columnIndex);
                }
            }
            else{
                rs.absolute(rowIndex+startPage+1);
                return rs.getObject(columnIndex+1);
            }
                
        } catch (SQLException ex)
        {
            ex.printStackTrace();
            return "";
        }
    }
    
    /**
     * 
     * @param value
     * @param row
     * @param col
     */
    @Override
    public void setValueAt(Object value, int row, int col) {
        if(!isDataEmpty()){
            if(col==0){
                list.set(row+startPage, value);
                if(value.equals(true))
                    this.jumlahDipilih++;
                else
                    this.jumlahDipilih--;
                fireTableCellUpdated(row, 0);
            }
        }
    }

    /**
     * 
     * @param c
     * @return
     */
    @Override
    public Class getColumnClass(int c) {
        if(isDataEmpty()) 
            return null;  
        
        return getValueAt(0, c).getClass();
    }
    
    /**
     * 
     * @param row
     * @param col
     * @return
     */
    @Override
    public boolean isCellEditable(int row, int col) {
        if(!isUsingPilihan)
            return false;
        
        if (col == 0) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * 
     * @return
     */
    public int getRowCount()
    {
        return jumlahBaris;
    }

    public int getAllRowCount()
    {
        return this.jumlahBarisTotal;
    }
    /**
     * 
     * @return
     */
    public int getColumnCount()
    {
        return namaKolom.length;
    }

    /**
     * 
     * @param column
     * @return
     */
    @Override
    public String getColumnName(int column)
    {
        String retValue;
        
        retValue = namaKolom[column];
        return retValue;
    }
    
    /**
     * 
     * @param query
     * @throws java.sql.SQLException
     * @throws java.lang.IllegalStateException
     */
    public void runQuery(String query)
    throws SQLException,IllegalStateException{
        if(query.toUpperCase().startsWith("SELECT")){
            rs = theKoneksi.executeSelect(query);
            if(isDataEmpty()){
                jumlahBarisTotal = 0;
                jumlahBaris = 0;
            }
            else{
                rs.last();
                jumlahBarisTotal = rs.getRow();
                if(!isUsingPilihan)
                    jumlahBaris = jumlahBarisTotal;

                if(!lastQuery.equalsIgnoreCase(query) && this.isUsingPilihan){
                    list = new LinkedList();

                    for(int i=0;i<jumlahBarisTotal;i++){
                        list.add(true);
                        this.jumlahDipilih++;
                    }
                }
            }
            this.fireTableDataChanged();
        }else{
            theKoneksi.executeUpdate(query);
        }
        lastQuery = query;
    }
    
    public LinkedList getDipilih() throws SQLException
    {
        if(isDataEmpty())
            return null;
        
        LinkedList set = new LinkedList();
        rs.first();
        for(int i=0;i<list.size();i++)
        {
            if(list.get(i).equals(true)){
                set.add(rs.getString("ID_DOK"));
            }
            rs.next();
        }
        return set;
    }
    
    /**
     * 
     */
    public void setEmpty(){
        jumlahBaris = 0;
        jumlahBarisTotal = 0;
        rs = null;
        this.fireTableDataChanged();
    }
    
    /**
     * 
     * @param status
     */
    public void setSemuaPilihan(boolean status)
    {
        this.jumlahDipilih = 0;
        if(this.isUsingPilihan){
            if(status)
                this.jumlahDipilih = this.jumlahBarisTotal;
            else
                this.jumlahDipilih = 0;
            for(int i=0;i<this.jumlahBarisTotal;i++){
                list.set(i, status);   
                this.fireTableCellUpdated(i, 0);
            }
        }
    }
    
    /**
     * 
     * @param status
     * @param page
     */
    public void setSemuaPilihanOnPage(boolean status)
    {
        if(this.isUsingPilihan){
            for(int i=0;i<this.jumlahBaris;i++){
                list.set(i+this.startPage, status);
                this.fireTableCellUpdated(i, 0);
            }  
            countJumlahDipilih();
        }
    }
    
    public void setPilihan(boolean status, int[] row)
    {
        for(int i : row){
            list.set(i+startPage, status);
        }
        this.fireTableDataChanged();
    }
    
    /**
     * 
     * @return
     */
    public int getJumlahDipilih() {
        countJumlahDipilih();
        return jumlahDipilih;
    }
    
    private void countJumlahDipilih(){
        int count=0;
        for(int i=0;i<this.jumlahBarisTotal;i++)
        {
            if(list.get(i).equals(true))
                count++;
        }
        this.jumlahDipilih = count;
    }
 
    private boolean isDataEmpty()
    {
        if(rs==null)
            return true;
        else{
            try {
                if (rs.first()) {
                    return false;
                }
            } catch (SQLException ex) {
                return true;
            }
        }
        return true;
    }
}
